﻿using JX.Core;
using JX.Core.Entity;
using JX.Infrastructure.Common;
using JX.Infrastructure.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace JX.Application
{
	/// <summary>
	/// 数据库表：FlowProcess 的应用层服务接口实现类.
	/// </summary>
	public partial class FlowProcessServiceAppDapper : ServiceAppDapper<FlowProcessEntity>, IFlowProcessServiceAppDapper
	{
		#region 仓储接口
		private readonly IRolesProcessRepositoryDapper _RolesProcessRepository;
		private readonly IProcessStatusCodeRepositoryDapper _ProcessStatusCodeRepository;
		/// <summary>
		/// 构造器注入
		/// </summary>
		/// <param name="repository"></param>
		/// <param name="RolesProcessRepository"></param>
		/// <param name="ProcessStatusCodeRepository"></param>
		public FlowProcessServiceAppDapper(IFlowProcessRepositoryDapper repository,
			IRolesProcessRepositoryDapper RolesProcessRepository,
			IProcessStatusCodeRepositoryDapper ProcessStatusCodeRepository) : base(repository)
		{
			m_repository = repository;
			_RolesProcessRepository = RolesProcessRepository;
			_ProcessStatusCodeRepository = ProcessStatusCodeRepository;
		}
		#endregion

		#region 添加
		/// <summary>
		/// 添加任务进程
		/// </summary>
		/// <param name="flowProcessInfo"></param>
		/// <returns></returns>
		public override bool Add(FlowProcessEntity flowProcessInfo)
		{
			bool flag = false;
			if (flowProcessInfo.FlowID > 0)
			{
				flag = base.Add(flowProcessInfo);
			}
			return flag;
		}
		/// <summary>
		/// 为指定角色集添加任务进程
		/// </summary>
		/// <param name="flowProcessInfo"></param>
		/// <param name="statusCodes"></param>
		/// <param name="roleIds"></param>
		/// <returns></returns>
		public bool Add(FlowProcessEntity flowProcessInfo, string statusCodes, string roleIds)
		{
			bool[] flagArray = new bool[] { true, true, true };//添加任务进程是否成功；添加状态码是否成功；添加角色关系是否成功；
			bool flag = false;
			if (Add(flowProcessInfo))
			{
				if (!string.IsNullOrEmpty(statusCodes))
				{
					flagArray[1] = AddStatusCodeToProcessStatusCode(flowProcessInfo.FlowID.ToInt32(), flowProcessInfo.ProcessID.ToInt32(), statusCodes);
				}
				if (!string.IsNullOrEmpty(roleIds))
				{
					flagArray[2] = AddGroupToProcessGroup(flowProcessInfo.FlowID.ToInt32(), flowProcessInfo.ProcessID.ToInt32(), roleIds);
				}
			}
			else
			{
				flagArray[0] = false;
			}
			if (flagArray[0] && flagArray[1] && flagArray[2])
			{
				flag = true;
			}
			return flag;
		}
		/// <summary>
		/// 添加角色到工作流进程
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="processId"></param>
		/// <param name="groupIds">多个ID用“,”分隔</param>
		/// <returns></returns>
		public bool AddGroupToProcessGroup(int flowId, int processId, string groupIds)
		{
			bool flag = false;
			if (!DataValidator.IsValidId(groupIds))
			{
				return false;
			}
			foreach (string str in groupIds.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
			{
				flag = _RolesProcessRepository.Add(new RolesProcessEntity { FlowID = flowId, ProcessID = processId, RoleID = str.ToInt32() });
				if (!flag)
				{
					DeleteGroupInProcess(flowId, processId);
					return flag;
				}
			}
			return flag;
		}
		/// <summary>
		/// 添加工作流程状态码 ProcessStatusCode
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="processId"></param>
		/// <param name="stateCodesId"></param>
		/// <returns></returns>
		public bool AddStatusCodeToProcessStatusCode(int flowId, int processId, string stateCodesId)
		{
			if (!DataValidator.IsValidId(stateCodesId))
			{
				return false;
			}
			foreach (string str in stateCodesId.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
			{
				if (!_ProcessStatusCodeRepository.Add(new ProcessStatusCodeEntity { FlowID = flowId, ProcessID = processId, StatusCode = str.ToInt32() }))
				{
					return false;
				}
			}
			return true;
		}
		#endregion

		#region 删除
		/// <summary>
		/// 删除工作流任务进程及相关信息
		/// </summary>
		/// <param name="flowId">流程ID</param>
		/// <returns></returns>
		public bool Delete(int flowId)
		{
			bool flag = false;
			bool[] flagArray = new bool[] { true, true, true };
			if (ExistWorkFlowInProcessRole(flowId))
			{
				flagArray[0] = DeleteWorkFlowInProcessRole(flowId);
			}
			if (ExistWorkFlowInProcessStatusCode(flowId))
			{
				flagArray[1] = DeleteWorkFlowInProcessStatusCode(flowId);
			}
			flagArray[2] = Delete(p => p.FlowID == flowId);
			if ((flagArray[0] && flagArray[1]) && flagArray[2])
			{
				flag = true;
			}
			return flag;
		}
		/// <summary>
		/// 删除工作流任务进程
		/// </summary>
		/// <param name="flowId">流程ID</param>
		/// <param name="processId">步骤ID</param>
		/// <returns></returns>
		public bool Delete(int flowId, int processId)
		{
			bool flag = false;
			bool[] flagArray = new bool[] { true, true, true };
			if (ExistRoleInProcessRole(flowId, processId))
			{
				flagArray[0] = DeleteGroupInProcess(flowId, processId);
			}
			if (ExistStatusCodeInProcessStatusCode(flowId, processId))
			{
				flagArray[1] = DeleteStatusCodeInProcessStatusCode(flowId, processId);
			}
			flagArray[2] = Delete(p => p.FlowID == flowId && p.ProcessID == processId);
			if ((flagArray[0] && flagArray[1]) && flagArray[2])
			{
				flag = true;
			}
			return flag;
		}
		/// <summary>
		/// 删除指定工作流的所有审核角色
		/// </summary>
		/// <param name="flowId">流程ID</param>
		/// <returns></returns>
		public bool DeleteWorkFlowInProcessRole(int flowId)
		{
			return _RolesProcessRepository.Delete(p => p.FlowID == flowId);
		}
		/// <summary>
		/// 删除指定工作流的、指定步骤的所有审核角色
		/// </summary>
		/// <param name="flowId">流程ID</param>
		/// <param name="processId">步骤ID</param>
		/// <returns></returns>
		public bool DeleteGroupInProcess(int flowId, int processId)
		{
			return _RolesProcessRepository.Delete(p => p.FlowID == flowId && p.ProcessID == processId);
		}

		/// <summary>
		/// 删除工作流的审核状态码
		/// </summary>
		/// <param name="statusCode"></param>
		/// <returns></returns>
		public bool DeleteStatusCodeInProcessStatusCode(int statusCode)
		{
			return _ProcessStatusCodeRepository.Delete(p => p.StatusCode == statusCode);
		}
		/// <summary>
		///  删除指定工作流程的、指定步骤的审核状态码
		/// </summary>
		/// <param name="flowId">流程ID</param>
		/// <param name="processId">步骤ID</param>
		/// <returns></returns>
		public bool DeleteStatusCodeInProcessStatusCode(int flowId, int processId)
		{
			return _ProcessStatusCodeRepository.Delete(p => p.FlowID == flowId && p.ProcessID == processId);
		}
		/// <summary>
		/// 删除指定工作流的所有审核状态码
		/// </summary>
		/// <param name="flowId">流程ID</param>
		/// <returns></returns>
		public bool DeleteWorkFlowInProcessStatusCode(int flowId)
		{
			return _ProcessStatusCodeRepository.Delete(p => p.FlowID == flowId);
		}
		#endregion

		#region 修改
		/// <summary>
		/// 批量更新工作流流程信息
		/// </summary>
		/// <param name="flowProcessInfo"></param>
		/// <param name="statusCodes"></param>
		/// <param name="roleIds"></param>
		/// <returns></returns>
		public bool Update(FlowProcessEntity flowProcessInfo, string statusCodes, string roleIds)
		{
			bool[] flagArray = new bool[] { true, true, true };
			bool flag = false;
			if (flowProcessInfo != null)
			{
				flagArray[0] = Update(flowProcessInfo);
			}
			if ((flowProcessInfo != null) && !string.IsNullOrEmpty(statusCodes))
			{
				flagArray[1] = UpdateStatusCodeInProcessStatusCode(flowProcessInfo.FlowID.ToInt32(), flowProcessInfo.ProcessID.ToInt32(), statusCodes);
			}
			if ((flowProcessInfo != null) && !string.IsNullOrEmpty(roleIds))
			{
				flagArray[2] = UpdateRoleInProcessRole(flowProcessInfo.FlowID.ToInt32(), flowProcessInfo.ProcessID.ToInt32(), roleIds);
			}
			if ((flagArray[0] && flagArray[1]) && flagArray[2])
			{
				flag = true;
			}
			return flag;
		}
		/// <summary>
		/// 更新工作流中的角色信息
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="processId"></param>
		/// <param name="roleIds"></param>
		/// <returns></returns>
		public bool UpdateRoleInProcessRole(int flowId, int processId, string roleIds)
		{
			if (!DataValidator.IsValidId(roleIds))
			{
				return false;
			}
			DeleteGroupInProcess(flowId, processId);
			return AddGroupToProcessGroup(flowId, processId, roleIds);
		}
		/// <summary>
		/// 更新工作流审核记录
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="processId"></param>
		/// <param name="stateCodesId"></param>
		/// <returns></returns>
		public bool UpdateStatusCodeInProcessStatusCode(int flowId, int processId, string stateCodesId)
		{
			if (!DataValidator.IsValidId(stateCodesId))
			{
				return false;
			}
			DeleteStatusCodeInProcessStatusCode(flowId, processId);
			return AddStatusCodeToProcessStatusCode(flowId, processId, stateCodesId);
		}
		#endregion

		#region 存在数据
		/// <summary>
		/// 判断是否存在指定工作流的处理进程
		/// </summary>
		/// <param name="flowId"></param>
		/// <returns></returns>
		public bool ExistWorkFlowInFlowProcess(int flowId)
		{
			return m_repository.IsExist(p => p.FlowID == flowId);
		}
		/// <summary>
		/// 判断指定工作流进程是否存在
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="processName"></param>
		/// <returns></returns>
		public bool ExistFlowProcess(int flowId, string processName)
		{
			return m_repository.IsExist(p => p.FlowID == flowId && p.ProcessName == processName);
		}
		/// <summary>
		/// 判断角色是否包含在工作流流程中
		/// </summary>
		/// <param name="roleId"></param>
		/// <returns></returns>
		public bool ExistRoleInProcessRole(int roleId)
		{
			return _RolesProcessRepository.IsExist(p=>p.RoleID==roleId);
		}
		/// <summary>
		/// 判断是否存在指定工作流的审核角色
		/// </summary>
		/// <param name="flowId"></param>
		/// <returns></returns>
		public bool ExistWorkFlowInProcessRole(int flowId)
		{
			return _RolesProcessRepository.IsExist(p => p.FlowID == flowId);
		}
		/// <summary>
		/// 判断工作流流程中是否存在角色
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="processId"></param>
		/// <returns></returns>
		public bool ExistRoleInProcessRole(int flowId, int processId)
		{
			return _RolesProcessRepository.IsExist(p => p.FlowID == flowId && p.ProcessID == processId);
		}
		/// <summary>
		/// 是否存在指定的审核状态码
		/// </summary>
		/// <param name="statusCode"></param>
		/// <returns></returns>
		public bool ExistStatusCodeInProcessStatusCode(int statusCode)
		{
			return _ProcessStatusCodeRepository.IsExist(p => p.StatusCode==statusCode);
		}
		/// <summary>
		/// 判断是否存在指定工作流的审核状态码
		/// </summary>
		/// <param name="flowId"></param>
		/// <returns></returns>
		public bool ExistWorkFlowInProcessStatusCode(int flowId)
		{
			return _ProcessStatusCodeRepository.IsExist(p => p.FlowID == flowId);
		}
		/// <summary>
		///  判断指定工作流进程中是否存在审核状态码
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="processId"></param>
		/// <returns></returns>
		public bool ExistStatusCodeInProcessStatusCode(int flowId, int processId)
		{
			return _ProcessStatusCodeRepository.IsExist(p => p.FlowID == flowId && p.ProcessID == processId);
		}
		#endregion

		#region 得到实体
		/// <summary>
		/// 获取工作流流程信息
		/// </summary>
		/// <param name="flowId">流程ID</param>
		/// <param name="processId">步骤ID</param>
		/// <returns></returns>
		public FlowProcessEntity GetFlowProcessById(int flowId, int processId)
		{
			return m_repository.Get(p => p.FlowID == flowId && p.ProcessID == processId);
		}
		/// <summary>
		/// 获取工作流流程信息
		/// </summary>
		/// <param name="flowId">流程ID</param>
		/// <param name="roleId">角色ID</param>
		/// <returns></returns>
		public FlowProcessEntity GetFlowProcessByRoles(int flowId, int roleId)
		{
			return m_repository.Get("FlowID = @FlowID AND ProcessID = (SELECT ProcessID FROM RolesProcess WHERE FlowID = @FlowID AND RoleId = @RoleId)", new { FlowID = flowId, RoleId = roleId });
		}
		/// <summary>
		/// 获取工作流流程信息
		/// </summary>
		/// <param name="flowId">流程ID</param>
		/// <param name="roleIdArr">角色ID，多个ID用“,”分隔</param>
		/// <returns></returns>
		public FlowProcessEntity GetFlowProcessByRoles(int flowId, string roleIdArr)
		{
			if (!DataValidator.IsValidId(roleIdArr))
			{
				return null;
			}
			return m_repository.Get("FlowID = @FlowID AND ProcessID in (SELECT ProcessID FROM RolesProcess WHERE FlowID = @FlowID AND RoleId in @RoleIds) ORDER BY PassActionStatus DESC", new { FlowID = flowId, RoleIds = StringHelper.GetArrayBySplit<int>(roleIdArr).ToArray() });
		}
		#endregion

		#region 得到实体列表
		/// <summary>
		/// 获取工作流流程信息列表
		/// </summary>
		/// <param name="flowId">流程ID</param>
		/// <returns></returns>
		public IList<FlowProcessEntity> GetFlowProcessList(int flowId)
		{
			Expression<Func<FlowProcessEntity, bool>> predicate = p => true;
			if(flowId > 0)
			{
				predicate = predicate.And(p => p.FlowID == flowId);
			}
			Expression<Func<IQueryable<FlowProcessEntity>, IOrderedQueryable<FlowProcessEntity>>> orderby = p => p.OrderByDescending(item => item.ProcessID);
			return m_repository.GetList(predicate, orderby).ToList();
		}
		#endregion

		#region 得到审核角色
		/// <summary>
		/// 获取工作流流程中的所有角色ID集
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="processId"></param>
		/// <returns></returns>
		public string GetGroupIdByProcessIdAndFlowId(int flowId, int processId)
		{
			var list = _RolesProcessRepository.GetAllData(selector: p => p.RoleID, predicate: p => p.FlowID == flowId && p.ProcessID == processId).ToArray();
			return string.Join(",",list);
		}
		/// <summary>
		/// 获取工作流流程角色列表
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="processId"></param>
		/// <returns></returns>
		public IList<RolesEntity> GetProcessRoleList(int flowId, int processId)
		{
			IList<RolesEntity> result = new List<RolesEntity>();
			var list = _RolesProcessRepository.GetList(p => p.FlowID == flowId && p.ProcessID == processId, p => p.OrderByDescending(item => item.ProcessID)).ToList();
			list.ForEach(item =>
			{
				RolesEntity rolesEntity = new RolesEntity();
				rolesEntity.RoleID = item.RoleID;
				result.Add(rolesEntity);
			});
			return result;
		}
		#endregion

		#region 得到审核状态码
		/// <summary>
		/// 获取指定角色列表的工作流审核状态码集
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="rolesId"></param>
		/// <returns></returns>
		public string GetStatusCodeToProcessStatusCode(int flowId, string rolesId)
		{
			if (!DataValidator.IsValidId(rolesId))
			{
				return string.Empty;
			}
			var list = _ProcessStatusCodeRepository.GetAllData<string>("", "FlowID = @FlowID AND ProcessID IN (SELECT ProcessID FROM RolesProcess WHERE FlowID = @FlowID AND RoleID IN (" + rolesId + "))", new { FlowID = flowId }, "StatusCode");
			return string.Join(",", list);
		}
		/// <summary>
		/// 获取指定工作流程进程的状态码
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="processId"></param>
		/// <returns></returns>
		public IList<StatusEntity> GetProcessStatusCodeList(int flowId, int processId)
		{
			IList<StatusEntity> result = new List<StatusEntity>();
			var list = _ProcessStatusCodeRepository.GetList(p => p.FlowID == flowId && p.ProcessID == processId, p => p.OrderByDescending(item => item.ProcessID)).ToList();
			list.ForEach(item =>
			{
				StatusEntity entity = new StatusEntity();
				entity.StatusCode = item.StatusCode;
				result.Add(entity);
			});
			return result;
		}
		#endregion
	}
}